﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TJDevHouse.Starcraft.Game
{
	abstract public class Tile
	{

		public int X { get; private set; }
		public int Y { get; private set; }

		public bool IsWalkable
		{
			get
			{
				return GetIsWalkable();
			}
			set
			{
				SetIsWalkable(value);
			}
		}

		public bool IsHighGround
		{
			get
			{
				return GetHeight();
			}
			set
			{
				SetHeight(value);
			}
		}

		public bool IsBuildable
		{
			get
			{
				return GetIsBuildable();
			}
			set
			{
				SetIsBuildable(value);
			}
		}

		public BuildTile BuildTile
		{
			get
			{
				return GetBuildTile();
			}
		}

		public List<WalkTile> WalkTiles
		{
			get
			{
				return GetWalkTiles();
			}
		}

		public BuildTileMapCoordinate BuildTileCoordinate
		{
			get
			{
				return new BuildTileMapCoordinate(BuildTile.X, BuildTile.Y);
			}
		}

		public Map Map { get; protected set; }

		public Tile(Map map, int x, int y)
		{
			Map = map;
			X = x;
			Y = y;
		}

		/// <summary>
		/// Whether or not this tile is walkable.
		/// </summary>
		/// <returns></returns>
		public abstract bool GetIsWalkable();

		public abstract void SetIsWalkable(bool walkable);

		/// <summary>
		/// The height of this tile
		/// </summary>
		/// <returns></returns>
		public abstract bool GetHeight();
		public abstract void SetHeight(bool height);

		/// <summary>
		/// Whether it's possible to build on this tile or not.
		/// </summary>
		/// <returns></returns>
		public abstract bool GetIsBuildable();
		public abstract void SetIsBuildable(bool buildable);

		public override string ToString()
		{

			return X + "," + Y;
		}

		/// <summary>
		/// Calculate the distance between this and another map tile.
		/// </summary>
		/// <param name="mapTile"></param>
		/// <returns></returns>
		public double CalcDistance(BuildTile buildTile)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Returns a list of units on this tile.
		/// 
		/// Note: a unit can appear on more than one tile at any one time as they are normally
		/// more than one map tile wide and high.
		/// </summary>
		/// <returns></returns>
		/*
		public List<Unit> GetUnitsOnTile()
		{
			throw new NotImplementedException();
		}
		*/

		/// <summary>
		/// Whether or not this map tile is within the map boundaries. (i.e. is it a valid tile)
		/// </summary>
		/// <returns></returns>
		public bool IsOutOfBounds()
		{
			return !(X >= 0 && Y >= 0 && X < Map.MapBuildWidth && Y < Map.MapBuildHeight);
		}

		public abstract BuildTile GetBuildTile();

		public abstract List<WalkTile> GetWalkTiles();
	}
}
